package com.doubao.chat.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.doubao.chat.dto.ChatContextDTO;
import com.doubao.chat.dto.ChatMessageDTO;
import com.doubao.chat.dto.ChatSessionDTO;
import com.doubao.chat.dto.request.*;
import com.doubao.chat.entity.ChatMessage;
import com.doubao.chat.entity.ChatSession;
import com.doubao.chat.mapper.ChatMessageMapper;
import com.doubao.chat.service.ChatMessageService;
import com.doubao.chat.service.ChatSessionService;
import com.doubao.common.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import jakarta.validation.Valid;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/chat")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "聊天服务", description = "聊天相关接口")
public class ChatController {

    private final ChatSessionService sessionService;
    private final ChatMessageService messageService;
    private final ChatMessageMapper messageMapper;

    /**
     * 创建会话
     */
    @PostMapping("/session")
    @Operation(summary = "创建会话", description = "创建新的聊天会话")
    public Result<ChatSessionDTO> createSession(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody CreateSessionRequest request) {
        return sessionService.createSession(userId, request);
    }

    /**
     * 获取会话列表
     */
    @GetMapping("/sessions")
    @Operation(summary = "获取会话列表", description = "分页获取用户的聊天会话列表")
    public Result<IPage<ChatSessionDTO>> getSessionList(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid GetSessionListRequest request) {
        return sessionService.getSessionList(userId, request);
    }

    /**
     * 获取会话详情
     */
    @GetMapping("/session/{sessionId}")
    @Operation(summary = "获取会话详情", description = "获取指定会话的详细信息")
    public Result<ChatSessionDTO> getSessionDetail(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Parameter(description = "会话ID") @PathVariable Long sessionId) {
        return sessionService.getSessionDetail(userId, sessionId);
    }

    /**
     * 更新会话
     */
    @PutMapping("/session")
    @Operation(summary = "更新会话", description = "更新会话信息，如标题等")
    public Result<Void> updateSession(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody UpdateSessionRequest request) {
        return sessionService.updateSession(userId, request);
    }

    /**
     * 删除会话
     */
    @DeleteMapping("/session/{sessionId}")
    @Operation(summary = "删除会话", description = "删除指定的聊天会话")
    public Result<Void> deleteSession(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Parameter(description = "会话ID") @PathVariable Long sessionId) {
        return sessionService.deleteSession(userId, sessionId);
    }

    /**
     * 批量删除会话
     */
    @DeleteMapping("/sessions")
    @Operation(summary = "批量删除会话", description = "批量删除指定的聊天会话")
    public Result<Void> batchDeleteSessions(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody BatchDeleteSessionRequest request) {
        return sessionService.batchDeleteSessions(userId, request);
    }

    /**
     * 清空会话消息
     */
    @PostMapping("/session/clear")
    @Operation(summary = "清空会话消息", description = "清空指定会话的所有消息")
    public Result<Void> clearSession(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody ClearSessionRequest request) {
        return sessionService.clearSession(userId, request);
    }

    /**
     * 导出会话
     */
    @PostMapping("/session/export")
    @Operation(summary = "导出会话", description = "导出会话聊天记录为文件")
    public Result<String> exportSession(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody ExportSessionRequest request) {
        return sessionService.exportSession(userId, request);
    }

    /**
     * 获取会话上下文
     */
    @GetMapping("/context/{sessionId}")
    @Operation(summary = "获取会话上下文", description = "获取指定会话的完整上下文信息")
    public Result<ChatContextDTO> getSessionContext(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Parameter(description = "会话ID") @PathVariable Long sessionId) {
        return sessionService.getSessionContext(userId, sessionId);
    }

    /**
     * 发送消息
     */
    @PostMapping("/message")
    @Operation(summary = "发送消息", description = "发送消息并获取回复")
    public Result<ChatMessageDTO> sendMessage(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody SendMessageRequest request) {
        return messageService.sendMessage(userId, request);
    }

    /**
     * 流式发送消息
     */
    @PostMapping("/message/stream")
    @Operation(summary = "流式发送消息", description = "发送消息并以流式方式获取回复")
    public SseEmitter sendMessageStream(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody SendMessageRequest request) {
        return messageService.sendMessageStream(userId, request);
    }

    /**
     * 获取消息列表
     */
    /**
     * 获取消息列表
     */
    @GetMapping("/messages")
    public Result<IPage<ChatMessageDTO>> getMessageList(
            @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @RequestParam(required = false) Map<String, String> params) {

        try {
            // 从params中提取参数
            Long deviceId = null;
            Long sessionId = null;
            Integer page = 1;
            Integer size = 20;
            Long maxId = null;

            // 处理直接请求参数
            if (params.containsKey("deviceId")) {
                try {
                    deviceId = Long.parseLong(params.get("deviceId"));
                } catch (NumberFormatException e) {
                    log.warn("无效的deviceId参数: {}", params.get("deviceId"));
                }
            }

            if (params.containsKey("sessionId")) {
                try {
                    sessionId = Long.parseLong(params.get("sessionId"));
                } catch (NumberFormatException e) {
                    log.warn("无效的sessionId参数: {}", params.get("sessionId"));
                }
            }

            if (params.containsKey("page")) {
                try {
                    page = Integer.parseInt(params.get("page"));
                } catch (NumberFormatException e) {
                    log.warn("无效的page参数，使用默认值1");
                }
            }

            if (params.containsKey("size")) {
                try {
                    size = Integer.parseInt(params.get("size"));
                } catch (NumberFormatException e) {
                    log.warn("无效的size参数，使用默认值20");
                }
            }

            if (params.containsKey("maxId")) {
                try {
                    maxId = Long.parseLong(params.get("maxId"));
                } catch (NumberFormatException e) {
                    log.warn("无效的maxId参数");
                }
            }

            // 处理嵌套params参数情况
            if (deviceId == null && params.containsKey("params[deviceId]")) {
                try {
                    deviceId = Long.parseLong(params.get("params[deviceId]"));
                } catch (NumberFormatException e) {
                    log.warn("无效的嵌套deviceId参数");
                }
            }

            log.info("获取消息列表: userId={}, deviceId={}, sessionId={}, page={}, size={}",
                    userId, deviceId, sessionId, page, size);

            if (userId == null) {
                return Result.failed("用户未登录");
            }

            // 以下逻辑与原来相同
            // 如果提供了会话ID，直接查询
            if (sessionId != null) {
                GetMessageListRequest request = new GetMessageListRequest();
                request.setSessionId(sessionId);
                request.setPage(page);
                request.setSize(size);
                request.setMaxId(maxId);
                return messageService.getMessageList(userId, request);
            }

            // 在控制器中
            if (deviceId != null) {
                log.info("尝试直接查询用户设备消息: userId={}, deviceId={}", userId, deviceId);
                int offset = (page - 1) * size;

                // 获取降序排列的消息（最新的在前）
                List<ChatMessage> directMessages = messageMapper.findByUserAndDevice(userId, deviceId, offset, size);

                if (directMessages != null && !directMessages.isEmpty()) {
                    log.info("找到直接关联的消息, 数量: {}", directMessages.size());

                    // 转换为DTO
                    List<ChatMessageDTO> messageDTOs = directMessages.stream().map(msg -> {
                        ChatMessageDTO dto = new ChatMessageDTO();
                        BeanUtils.copyProperties(msg, dto);
                        dto.setIsCurrentUser("user".equals(msg.getRole()));
                        return dto;
                    }).collect(Collectors.toList());

                    // 反转消息列表，使最新的消息在最后
                    Collections.reverse(messageDTOs);

                    Page<ChatMessageDTO> resultPage = new Page<>(page, size);
                    resultPage.setRecords(messageDTOs);
                    resultPage.setTotal(messageDTOs.size());
                    return Result.success(resultPage);
                }

                // 2. 如果直接查询无结果，再尝试查找最近的会话
                log.info("直接查询无结果，尝试查找最近会话: userId={}, deviceId={}", userId, deviceId);
                ChatSession session = sessionService.findRecentSession(userId, deviceId);
                if (session != null) {
                    log.info("找到最近会话: sessionId={}", session.getId());
                    GetMessageListRequest request = new GetMessageListRequest();
                    request.setSessionId(session.getId());
                    request.setPage(page);
                    request.setSize(size);
                    request.setMaxId(maxId);
                    return messageService.getMessageList(userId, request);
                } else {
                    log.info("未找到最近会话");
                }
            }

            // 如果以上方法都找不到消息，返回空列表
            log.info("未找到任何消息，返回空列表");
            Page<ChatMessageDTO> emptyPage = new Page<>(page, size);
            emptyPage.setRecords(Collections.emptyList());
            return Result.success(emptyPage);
        } catch (Exception e) {
            log.error("获取消息列表异常", e);
            return Result.failed("获取消息列表失败: " + e.getMessage());
        }
    }

    /**
     * 删除消息
     */
    @DeleteMapping("/message/{messageId}")
    @Operation(summary = "删除消息", description = "删除指定的消息")
    public Result<Void> deleteMessage(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Parameter(description = "消息ID") @PathVariable Long messageId) {
        return messageService.deleteMessage(userId, messageId);
    }

    /**
     * 重新生成回复
     */
    @PostMapping("/message/regenerate/{sessionId}/{messageId}")
    @Operation(summary = "重新生成回复", description = "重新生成AI回复消息")
    public Result<ChatMessageDTO> regenerateMessage(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Parameter(description = "会话ID") @PathVariable Long sessionId,
            @Parameter(description = "消息ID") @PathVariable Long messageId) {
        return messageService.regenerateMessage(userId, sessionId, messageId);
    }

    /**
     * 文本转语音
     */
    @PostMapping("/tts")
    @Operation(summary = "文本转语音", description = "将文本转换为语音")
    public Result<String> textToSpeech(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Valid @RequestBody TextToSpeechRequest request) {
        return messageService.textToSpeech(userId, request);
    }

    /**
     * 获取设备消息
     */
    @GetMapping("/device/messages")
    @Operation(summary = "获取设备消息", description = "获取用户与特定设备的消息")
    public Result<IPage<ChatMessageDTO>> getDeviceMessages(
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-ID", required = false) Long userId,
            @Parameter(description = "设备ID") @RequestParam Long deviceId,
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") Integer size) {

        log.info("获取设备消息: userId={}, deviceId={}, page={}, size={}", userId, deviceId, page, size);

        if (userId == null) {
            return Result.failed("用户未登录");
        }

        try {
            // 先查找最近的会话
            ChatSession session = sessionService.findRecentSession(userId, deviceId);

            if (session != null) {
                log.info("找到会话: sessionId={}", session.getId());

                // 构造请求
                GetMessageListRequest request = new GetMessageListRequest();
                request.setSessionId(session.getId());
                request.setPage(page);
                request.setSize(size);

                // 获取会话消息
                return messageService.getMessageList(userId, request);
            } else {
                log.info("未找到会话, 返回空列表");
                return Result.success(new Page<>());
            }
        } catch (Exception e) {
            log.error("获取设备消息异常", e);
            return Result.failed("获取设备消息失败: " + e.getMessage());
        }
    }
}